/*
                    Map Class Definition
*/

#ifndef MAP_H
#define MAP_H

#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/lexical_cast.hpp>

#include <string>
#include <vector>

#include "../Functions.h"
#include "../NetworkDefinitions.h"
#include "Tilelayer.h"
#include "Tile.h"
#include "Tilesheets.h"
#include "Collision.h"
#include "Collisionlayer.h"
#include "Event.h"
#include "Eventlayer.h"

using namespace std;
using boost::lexical_cast;
using boost::bad_lexical_cast;

class Map
{
    public:
        Map();
        ~Map();

        int getWidth();
        int getHeight();
        int getTilesWidth();
        int getTilesHeight();

        void setName(const string& strNewName);
        string getName();

        void setTilesheet(const string& strNewTilesheet);
        string getTilesheet();

        int BlitToSurface(SDL_Surface *surface, const SDL_Rect& view);
        int BlitLayerToSurface(SDL_Surface *surface, const int& iLayer, const SDL_Rect& view);
        int BlitFromLayerToSurface(SDL_Surface *surface, const int& iLayer, const SDL_Rect& view);

        int ImportFromXML(string strFilename);

        Point GetPlayerNextPosition(Point Position, int iDirection);
        int GetPlayerNextCollision(Point Position, int iDirection);
        int GetCollisionAtPoint(Point Position);

        Point FindSpawnPosition();

        Event* GetEventAtPosition(Point Position);

        boost::numeric::ublas::matrix<int> getCollisionMatrix();

    private:
        int AddEventLayer();

        int iWidth, iHeight;
        int iTilesWidth, iTilesHeight;
        int iTotalTiles;

        string strName;
        string strTilesheet;

        vector<Tilelayer*> Tilelayers;
        vector<Collisionlayer*> Collisionlayers;
        vector<Eventlayer*> Eventlayers;
        vector<SDL_Surface*> DrawingLayers;

        boost::numeric::ublas::matrix<int> CollisionMatrix;

        int iActiveCollisionLayer;

        // Import functions*********************************************************************************************
        int populate(string filename);
        string name();
        string tilesheetname();
        string width();
        string height();
        void parseTileLayer();
        void parseTileMap(xmlDocPtr doc, xmlNodePtr cur);
        void parseTile(xmlDocPtr doc, xmlNodePtr cur);
        void parseSheetPosition(xmlDocPtr doc, xmlNodePtr cur);
        void parseMapPosition(xmlDocPtr doc, xmlNodePtr cur);
        void parseCollisionLayer();

        void parseCollisionmap(string strMap);

        void GenerateDrawingLayers();

        void parseEventLayer();
        void parseEvent(xmlDocPtr doc, xmlNodePtr cur);
        void parseEventPosition(xmlDocPtr doc, xmlNodePtr cur);
        int iCurEvent;

        int GetTileByPosition(Point Position);

        Point tempts, tempmp;

        xmlDocPtr doc;
        xmlXPathContextPtr xpathRoot;
        //**************************************************************************************************************

        bool CheckLedge(const int& iDirection, const int& iLedgeType);
};

#endif
